package com.tn.utils
{
	import flash.events.TimerEvent;
	import flash.utils.Timer;

	public class TimeoutInvoker
	{

		/*============================================================================*/
		/* Private Properties                                                         */
		/*============================================================================*/

		private var delay:Number;

		/**
		 * The method to invoke. Only if timeOut is reached
		 */
		private var delegate:Function;

		/**
		 * @internal
		 */
		private var _timer:Timer;

		private function get timer():Timer
		{
			return _timer ||= new Timer(delay, 1);
		}

		/*============================================================================*/
		/* Constructor                                                                */
		/*============================================================================*/

		public function TimeoutInvoker(delay:Number = 2000)
		{
			this.delay = delay;
		}


		/*============================================================================*/
		/* Public Functions                                                           */
		/*============================================================================*/

		/**
		 * Reset the timer and release the delegate
		 */
		public function cancel():void
		{
			if (timer.running)
			{
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, timeoutReachedHandler);
			}
			delegate = null;
		}

		/**
		 * Call this method later unless another method is assigned in the interim
		 * in which case, reset the timer. This prevents request "flooding".
		 *
		 * @param method The method to call
		 * @param args The arguments to apply
		 */
		public function start(method:Function, ... args):void
		{
			timer.reset();
			timer.addEventListener(TimerEvent.TIMER, timeoutReachedHandler);

			delegate = function():void
			{
				method.apply(null, args);
			};
			timer.start();
		}

		/*============================================================================*/
		/* Private Functions                                                          */
		/*============================================================================*/

		private function timeoutReachedHandler(event:TimerEvent):void
		{
			timer.removeEventListener(TimerEvent.TIMER, timeoutReachedHandler);
			timer.stop();

			delegate && delegate();
		}
	}
}
